package com.inspire.tank;

import com.inspire.tank.cor.BulletTankCollider;
import com.inspire.tank.cor.Collider;
import com.inspire.tank.cor.ColliderChain;
import com.inspire.tank.cor.TankTankCollider;

import java.awt.*;
import java.io.*;
import java.util.ArrayList;

/**
 * @author inspire
 * @description 门面模式：对于TankGrame来说，之前要跟所有物体打交道，现在只需要跟GameModel打交道，所以这里的GameModel做门面模式
 *              中介（调停）模式：由于GameModel中用到了责任链模式，解耦了物体与物体之间打交道，所以每个物体可以只和GameModel打交道，这里GameModel做了中介模式
 * @date 2022/6/12 22:06
 */
public class GameModel {
    private static final GameModel INSTANCE=new GameModel();//先执行这一步，再执行init

    Tank myTank;

    ColliderChain colliderChain=new ColliderChain();

    private ArrayList<GameObject> gameObjects=new ArrayList<>();

    public static GameModel getInstance(){
        return INSTANCE;//饿汉式
    }

    static {
        INSTANCE.init();
    }

    private GameModel(){

    }

    private void init(){
        //初始化主战坦克
        myTank=new Tank(200,400,Dir.DOWN,Group.GOOD);

        int initTankCount = Integer.parseInt((String)PropertyMgr.get("initTankCount"));
        //初始化敌方坦克
        for(int i=0;i<initTankCount;i++){
            new Tank(50+i*80,200,Dir.DOWN,Group.BAD);
        }

        add(new Wall(150,150,200,50));
        add(new Wall(550,150,200,50));
        add(new Wall(300,300,50,200));
        add(new Wall(550,300,50,200));
    }

    public void add(GameObject gameObject){
        this.gameObjects.add(gameObject);
    }
    public void remove(GameObject gameObject){
        this.gameObjects.remove(gameObject);
    }
    public void paint(Graphics g) {
        Color c=g.getColor();
        g.setColor(Color.WHITE);
        /*g.drawString("子弹的数量:"+bullets.size(),10,60);
        g.drawString("敌人的数量:"+tanks.size(),10,80);
        g.drawString("爆炸的数量:"+explodes.size(),10,100);*/

        g.setColor(c);

        myTank.paint(g);
        for(int i=0;i<gameObjects.size();i++){
            gameObjects.get(i).paint(g);
        }

        for(int i=0;i<gameObjects.size();i++){
            for(int j=i+1;j<gameObjects.size();j++){
                GameObject gameObject1=gameObjects.get(i);
                GameObject gameObject2=gameObjects.get(j);
                colliderChain.collide(gameObject1,gameObject2);
            }
        }
        /*for(int i=0;i<bullets.size();i++){
            for(int j=0;j<tanks.size();j++){
                bullets.get(i).collidWidth(tanks.get(j));
            }
        }*/
    }

    public Tank getMainTan() {
        return myTank;
    }

    public void save() {
        File f=new File("site/sources/tank.data");
        ObjectOutputStream oos=null;
        try {
            oos=new ObjectOutputStream(new FileOutputStream(f));
            oos.writeObject(myTank);
            oos.writeObject(gameObjects);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(oos!=null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void load() {
        File f = new File("site/sources/tank.data");
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream(f));
            myTank=(Tank)ois.readObject();
            gameObjects=(ArrayList)ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(ois!=null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
